package com.deng.api.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.deng.api.dto.MenuDTO;
import com.deng.api.entity.AuthUser;
import com.deng.api.entity.MenuMeta;
import com.deng.api.entity.SysMenu;
import com.deng.api.service.ISysMenuService;
import com.deng.api.utils.RedisUtil;
import com.deng.api.vo.MenuVO;
import com.deng.api.vo.PageVO;
import com.deng.commons.common.BaseResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统菜单 前端控制器
 * </p>
 *
 * @author deng
 * @since 2022-08-10
 */
@Slf4j
@RestController
@RequestMapping("/api/menus")
@Api(tags = "权限菜单接口")
public class SysMenuController {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private ISysMenuService iSysMenuService;
    @Resource
    private RedisUtil redisUtil;
    /**
     * 步骤：
     *  （1）需要获取当前用户id，然后根据id去查找对应的权限菜单，需要关联表 sys_role
     *          sys_roles_menu  sys_menu
     *  （2）把Menu转换为MenuDTO
     *  （3）构建tree形状的父子菜单级别
     *  （4）需要把menuDTO转化为MenuVO进行返回
     *   最后对菜单显示进行排序
     */
    @GetMapping("/build")
    @ApiOperation("返回前端页面展示菜单")
    public BaseResult build(){
        AuthUser authUser = JSON.parseObject(stringRedisTemplate.opsForValue().get("authUser"), AuthUser.class);
//        AuthUser authUser = (AuthUser) redisUtil.get("authUser");
        List<SysMenu> menus = authUser.getMenus();
        //去除权限类型为2的====2为给权限的执行操作无需再权限列表下显示
        for (int i =0;i<menus.size();i++){
            if(StrUtil.equals(menus.get(i).getType().toString(),"2")){
                menus.remove(menus.get(i));
                i--;
            }
        }
        //把Menu转换为MenuDTO
        List<MenuDTO> menuDTOS = menus.stream().map(menu->MenuDTO.toDTO(menu)).collect(Collectors.toList());
        //构建tree形状的父子菜单级别
        List<MenuDTO> menuDTOSTree = buildTree(menuDTOS);
        //返回的list
        List<MenuVO> menuVOList = buildMenus(menuDTOSTree);
        //排序
        List<MenuVO> menuVOS =
                menuVOList.stream().sorted((m1,m2)-> m1.getMenuSort()-m2.getMenuSort()).collect(Collectors.toList());
        return BaseResult.success(menuVOS);
    }
    /**
     * 把读取到的MenuDTOs转换为tree形状的
     */
    public List<MenuDTO> buildTree(List<MenuDTO> menuDTOS){
        List<MenuDTO> tree = new ArrayList<>();
        for (MenuDTO menuDTO: menuDTOS) {
            //一级菜单
            if (menuDTO.getPid() == null){
                tree.add(menuDTO);
            }
            //给父级菜单添加子集菜单
            for (MenuDTO menuDTO2: menuDTOS) {
                //如果当前循环的dto是内循环dto2的父级id
                if (menuDTO.getId().equals(menuDTO2.getPid())){
                    if (menuDTO.getChildren() == null){
                        menuDTO.setChildren(new ArrayList<>());
                    }
                    //添加到子集列表中
                    menuDTO.getChildren().add(menuDTO2);
                }
            }
        }
        return tree;
    }

    /**
     * menuDTO转化为MenuVO
     */
    public List<MenuVO> buildMenus(List<MenuDTO> menuDTOS){
        List<MenuVO> menuVOList = new ArrayList<>();
        menuDTOS.forEach(menuDTO -> {
            MenuVO menuVO = new MenuVO();
            menuVO.setName(StrUtil.isEmptyIfStr(menuDTO.getName())?menuDTO.getTitle():menuDTO.getName());
            menuVO.setHidden(menuDTO.getHidden());
            menuVO.setMenuSort(menuDTO.getMenuSort());
            //如果是一级菜单，需要添加 /
            menuVO.setPath(menuDTO.getPid()==null? "/"+menuDTO.getPath():menuDTO.getPath());
            //本地页面处理
            if (!menuDTO.getIframe()){
                //一级菜单
                if (menuDTO.getPid() == null){
                    menuVO.setComponent(StrUtil.isBlankIfStr(menuDTO.getComponent())?
                            "Layout":menuDTO.getComponent());
                }else{
                    menuVO.setComponent(menuDTO.getComponent());
                }
            }
            //meta信息
            menuVO.setMeta(new MenuMeta(menuDTO.getIcon(),menuDTO.getTitle(),menuDTO.getCache()));
            //处理children
            List<MenuDTO> children = menuDTO.getChildren();
            if (CollectionUtil.isNotEmpty(children)){
                menuVO.setAlwaysShow(true);
                menuVO.setRedirect("noredirect");
                menuVO.setChildren(buildMenus(children));
            }
            menuVOList.add(menuVO);
        });
        return menuVOList;
    }

    @ApiOperation("返回子菜单-根据pid")
    @GetMapping("/lazy")
    public BaseResult lazy(@RequestParam Long pid){
        return iSysMenuService.getMenusByPid(pid);
    }

    @ApiOperation("返回角色的权限菜单ID")
    @GetMapping("/getRole")
    public BaseResult getMenusByRid(@RequestParam Long rid){
        return iSysMenuService.getMenuByRid(rid);
    }

    @ApiOperation("根据菜单ID返回所有子菜单ID")
    @GetMapping("/child")
    public BaseResult getChildren(@RequestParam Long id){
        return iSysMenuService.getChildren(id);
    }

    @ApiOperation("查询权限菜单（分页查询）")
    @GetMapping
    public BaseResult getMenus(@RequestParam(defaultValue = "1") Integer page,
                               @RequestParam(defaultValue = "10") Integer size,
                               Long pid){
        PageVO pageVO = iSysMenuService.getMenus(page, size, pid);
        return BaseResult.success(pageVO);
    }

    @ApiOperation("添加菜单")
    @PostMapping("/add")
    public BaseResult addMenu(@RequestBody SysMenu sysMenu){
        boolean res = iSysMenuService.adds(sysMenu);
        return BaseResult.result(res);
    }

    @ApiOperation("获取同级和上级菜单")
    @PostMapping("/superior")
    public BaseResult superior(@RequestBody Set<Long> ids){
        List<MenuDTO> dtos = iSysMenuService.getSuperior(ids);
        List<MenuDTO> menuDTOS = buildTree(dtos);
        return BaseResult.success(menuDTOS);
    }
    @ApiOperation("修改菜单")
    @PostMapping("/edit")
    public BaseResult editMenu(@RequestBody SysMenu sysMenu){
        return BaseResult.result(iSysMenuService.editMenu(sysMenu));
    }
    @ApiOperation("删除菜单")
    @DeleteMapping
    public BaseResult deleteMenu(@RequestBody Set<Long> ids){
        return BaseResult.result(iSysMenuService.deleteMenu(ids));
    }
}
